package com.delicaterock.andenginetest;

import java.util.Random;
import java.util.Vector;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.modifier.LoopEntityModifier;
import org.anddev.andengine.entity.modifier.ParallelEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.RotationModifier;
import org.anddev.andengine.entity.modifier.ScaleModifier;
import org.anddev.andengine.entity.modifier.SequenceEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.AutoParallaxBackground;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.scene.background.ParallaxBackground.ParallaxEntity;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.text.Text;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.HorizontalAlign;
import org.anddev.andengine.util.modifier.ease.EaseSineInOut;

import android.graphics.Color;
import android.graphics.Typeface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class MainScreen extends BaseGameActivity implements SensorEventListener {

    // ===========================================================
    // Constants
    // ===========================================================

    private static final int CAMERA_WIDTH = 720;
    private static final int CAMERA_HEIGHT = 480;

    // ===========================================================
    // Fields
    // ===========================================================

    private Sprite sprite;
    private Camera mCamera;
    private Texture mTexture;
    private TextureRegion mSpriteTextureRegion;
    private TextureRegion mDotTextureRegion;
    private SensorManager sensorManager;

    private float accellerometerSpeedX;
    private float accellerometerSpeedY;
    private float sX, sY; // Sprite coordinates
	private Texture mTexture2;
	private Texture mTexture3;
	private TextureRegion mBGRegion;
	private Vector<IShape> shapes = new Vector<IShape>();
	private Vector<IShape> weapons = new Vector<IShape>();
	private TextureRegion mParallaxLayerFront;
	private Texture mFontTexture;
	private Font mFont;
	private Scene scene;
	private TextureRegion mWeaponRegion;
	private Texture mTexture4;
	int deadEnemies = 0;
	final int TOTAL_ENEMY = 20;
	

    // ===========================================================
    // Constructors
    // ===========================================================

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================

    public Engine onLoadEngine() {
        this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
        return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
    }

    public void onLoadResources() {
        this.mTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
        this.mTexture2 = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mTexture3 = new Texture(1024, 1024, TextureOptions.DEFAULT);
		this.mTexture4 = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		
		this.mBGRegion = TextureRegionFactory.createFromAsset(this.mTexture3, this, "gfx/ocean.png", 0, 188);   
		this.mParallaxLayerFront = TextureRegionFactory.createFromAsset(this.mTexture3, this, "gfx/fish.png", 0, 0);
        this.mSpriteTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "gfx/sword32.png", 0, 0);
        this.mDotTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture2, this, "gfx/skull32.png", 0, 0);
        this.mWeaponRegion = TextureRegionFactory.createFromAsset(this.mTexture4, this, "gfx/reddot.png", 0, 0);

		this.mFontTexture = new Texture(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

		this.mFont = new Font(this.mFontTexture, Typeface.create(Typeface.DEFAULT, Typeface.BOLD), 32, true, Color.BLACK);
        
        this.mEngine.getTextureManager().loadTextures(this.mFontTexture, this.mTexture, this.mTexture2, this.mTexture3, this.mTexture4);
		this.mEngine.getFontManager().loadFont(this.mFont);
    }

    @SuppressWarnings("static-access")
    public Scene onLoadScene() {
        sensorManager = (SensorManager) this.getSystemService(this.SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), sensorManager.SENSOR_DELAY_GAME);
        
        this.mEngine.registerUpdateHandler(new FPSLogger());
        this.mEngine.registerUpdateHandler(new IUpdateHandler() {
            public void onUpdate(float pSecondsElapsed) {
                updateSpritePosition();
            }

            public void reset() {
                // TODO Auto-generated method stub
            }
        });

        scene = new Scene(1);
        
		final AutoParallaxBackground autoParallaxBackground = new AutoParallaxBackground(0, 0, 0, 5);
		autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(0.0f, new Sprite(0, 0, this.mBGRegion)));
		autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-10.0f, new Sprite(0, CAMERA_HEIGHT - this.mParallaxLayerFront.getHeight(), this.mParallaxLayerFront)));		
		scene.setBackground(autoParallaxBackground);
		
		createEnemies(scene);

        sX = (CAMERA_WIDTH - this.mSpriteTextureRegion.getWidth()) / 2;
        sY = (CAMERA_HEIGHT - this.mSpriteTextureRegion.getHeight()) / 2;

        sprite = new Sprite(sX, sY, this.mSpriteTextureRegion);
        sprite.setScale(1);
        scene.getLastChild().attachChild(sprite);
        
        Text textTitle = new Text(10, 10, this.mFont, getResources().getString(R.string.hello), HorizontalAlign.LEFT);
        scene.getLastChild().attachChild(textTitle);
        
		/* The actual collision-checking. */
		scene.registerUpdateHandler(new IUpdateHandler() {

			@Override
			public void reset() { }
			

			@Override
			public void onUpdate(final float pSecondsElapsed) {
//				if (deadEnemies>=TOTAL_ENEMY) {
//					if(mEngine.isRunning()) {
//						scene.setChildScene(scene, false, true, true);
//						mEngine.stop();
//				        Text textTitle = new Text(CAMERA_WIDTH/2, CAMERA_HEIGHT/2, mFont, getResources().getString(R.string.gameover), HorizontalAlign.LEFT);
//				        scene.getLastChild().attachChild(textTitle);						
//					}
//				}
				for (IShape shape:shapes) {
					for (IShape shape2:weapons) {
						if (shape2.collidesWith(sprite)) {
							shape2.setScale(6);
						} else {
							shape2.setScale(1);
						}
						if (shape.collidesWith(shape2)) {
							shape.setVisible(false);
							scene.detachChild(shape);
							deadEnemies++;
						}
					}					
					if  (shape.collidesWith(sprite)) {
						shape.setScale(2);
					} else {
						shape.setScale(1);
					}
				}
			}
		});
        

        return scene;
    }
    
    private void createEnemies(Scene scene) {
    	Random rnd = new Random(100);
    	for (int i=0; i<3; i++) {
    		int deltaX = rnd.nextInt(CAMERA_WIDTH);
    		int deltaY = rnd.nextInt(CAMERA_HEIGHT);
    		Path inPath = new Path(4).to(deltaX, deltaY).to(deltaX, CAMERA_HEIGHT - deltaY).to(CAMERA_WIDTH - deltaX, CAMERA_HEIGHT - deltaY).to(deltaX, deltaY);
    		Sprite sp = new Sprite(deltaX, deltaY, this.mWeaponRegion);
    		sp.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, inPath, null, EaseSineInOut.getInstance())));
    		scene.getLastChild().attachChild(sp);
    		weapons.add(sp);    		
    	}
    	
    	for (int i=0; i<TOTAL_ENEMY; i++) {
    		int deltaX = rnd.nextInt(CAMERA_WIDTH);
    		int deltaY = rnd.nextInt(CAMERA_HEIGHT);
    		Path inPath = new Path(4).to(deltaX, deltaY).to(deltaX, CAMERA_HEIGHT - deltaY).to(CAMERA_WIDTH - deltaX, CAMERA_HEIGHT - deltaY).to(deltaX, deltaY);
    		Sprite sp = new Sprite(deltaX, deltaY, this.mDotTextureRegion);
    		sp.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, inPath, null, EaseSineInOut.getInstance())));
    		scene.getLastChild().attachChild(sp);
    		shapes.add(sp);    		
    	}
    	
//        Path path = new Path(5).to(10, 10).to(10, CAMERA_HEIGHT - 74).to(CAMERA_WIDTH - 58, CAMERA_HEIGHT - 74).to(CAMERA_WIDTH - 58, 10).to(10, 10);
//        Sprite reddot = new Sprite(10,10, this.mDotTextureRegion);
//        reddot.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, path, null, EaseSineInOut.getInstance())));
//		scene.getLastChild().attachChild(reddot);
//		shapes.add(reddot);
//
//		path = new Path(3).to(10, 10).to(CAMERA_WIDTH - 58, CAMERA_HEIGHT - 74).to(10, 10);
//        reddot = new Sprite(10,10, this.mDotTextureRegion);
//        reddot.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, path, null, EaseSineInOut.getInstance())));
//		scene.getLastChild().attachChild(reddot);
//		shapes.add(reddot);
    }

    public void onLoadComplete() {

    }

    public void onSensorChanged(SensorEvent event) {
        synchronized (this) {
            switch (event.sensor.getType()) {
                case Sensor.TYPE_ACCELEROMETER:
                    accellerometerSpeedX = (int)event.values[1];
                    accellerometerSpeedY = (int)event.values[0];
                    break;
            }
        }
    }
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //
    }

    // ===========================================================
    // Methods
    // ===========================================================

    private void updateSpritePosition() {
        if ((accellerometerSpeedX != 0) || (accellerometerSpeedY != 0)) {
            // Set the Boundary limits
            int tL = 0;
            int lL = 0;
            int rL = CAMERA_WIDTH - (int)sprite.getWidth();
            int bL = CAMERA_HEIGHT - (int)sprite.getHeight();

            // Calculate New X,Y Coordinates within Limits
            if (sX >= lL) sX += accellerometerSpeedX; else sX = lL;
            if (sX <= rL) sX += accellerometerSpeedX; else sX = rL;
            if (sY >= tL) sY += accellerometerSpeedY; else sY = tL;
            if (sY <= bL) sY += accellerometerSpeedY; else sY = bL;

            // Double Check That New X,Y Coordinates are within Limits
            if (sX < lL)      sX = lL;
            else if (sX > rL) sX = rL;
            if (sY < tL)      sY = tL;
            else if (sY > bL) sY = bL;

            //sprite.setRotationCenter(sX, sY);
            //sprite.setRotation(300*(accellerometerSpeedX)/(accellerometerSpeedY+10));
            sprite.setRotation((float) Math.toDegrees(Math.atan2(accellerometerSpeedX, -accellerometerSpeedY)));
            sprite.setPosition(sX, sY);
            
        }
    }

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================    
}